﻿using System;
using System.Linq;
using Enyim.Caching;
using Ayatta.Contract;
using Web.Core.Extensions;
using Web.Core.OnlinePays;
using Web.Core.Controllers;
using Ayatta.Contract.Config;
using Ayatta.Contract.Domain;
using System.Collections.Generic;
using Ayatta.Contract.Component;

namespace Web.Pay.Controllers
{
    public abstract class BaseController : CoreController
    {

        protected BaseController(Lazy<IInfrastructureService> infrastructure, Lazy<IPassportService> passport, Lazy<IAccountService> account, Lazy<IStoreService> store, Lazy<ITradeService> trade, Lazy<IPlayService> play, Lazy<IMiscService> misc, Lazy<IExtraService> extra, IMemcachedClient memcachedClient)
            : base(infrastructure, passport, account, store, trade, play, misc, extra, memcachedClient)
        {
        }

        protected IOnlinePay GetOnlinePay(Platform platformId)
        {
            IOnlinePay pay = null;
            var platforms = PaymentPlatformList();

            var platform = platforms.FirstOrDefault(o => o.Id == platformId);

            if (platform != null)
            {
                pay = OnlinePayFactory.Create(platform);
                pay.Notified += Notified;
            }
            return pay;
        }

        /// <summary>
        /// 第三方支付平台通知验证成功后更新
        /// </summary>
        /// <param name="notification"></param>
        /// <returns></returns>
        private bool Notified(Notification notification)
        {
            var log = new AccountPaymentLog();
            var time = DateTime.Now;
            log.PayId = notification.No;
            log.PayNo = notification.PayNo;
            log.CreatedOn = time;
            if (!notification.Status)
            {
                //写入日志 
                log.Priority = 1;
                log.Subject = "验证签名失败";
                log.Message = "";
                Account.Value.AccountPaymentLogCreate(log);
                return false;
            }
            var payment = Account.Value.AccountPaymentGet(notification.No);
            if (payment != null)
            {
                log.UserId = payment.UserId;
                if (payment.Status)
                {
                    return true;
                }
                if (payment.Amount == notification.Amount)
                {
                    if (payment.Category == PaymentCategory.Recharge)
                    {
                        var status = Account.Value.AccountPaymentRechargeStatusUpdate(payment.Id, payment.ForeignKey, notification.PayTime, payment.ExternalNo);
                        if (status)
                        {
                            //InternalOrderHandler(payment);
                            log.Status = true;
                            return true;
                        }
                        else
                        {
                            //写入日志
                            log.Priority = 4;
                            log.Subject = "更新充值订单失败";
                            log.Message = "";
                            Account.Value.AccountPaymentLogCreate(log);
                            return false;
                        }
                    }
                    if(payment.Category == PaymentCategory.Order)
                    {
                        var status = Account.Value.AccountPaymentOrderPayByEBank(payment.Id, notification.PayTime, payment.ExternalNo);
                        if (status)
                        {
                            //InternalOrderHandler(payment);
                            log.Status = true;
                            return true;
                        }
                        else
                        {
                            //写入日志
                            log.Priority = 4;
                            log.Subject = "更新订单失败";
                            log.Message = "";
                            Account.Value.AccountPaymentLogCreate(log);
                            return false;
                        }
                    }
                }
                else
                {
                    //金额不一致
                    log.Priority = 3;
                    log.Subject = "金额不一致";
                    log.Message = "";
                    Account.Value.AccountPaymentLogCreate(log);
                }
            }
            else
            {
                //交易号不存在
                log.Priority = 2;
                log.Subject = "交易号不存在";
                log.Message = "";
                Account.Value.AccountPaymentLogCreate(log);
            }
            return false;
        }

        protected IList<RechargePackage> RechargePackageList(int userId)
        {
            var now = DateTime.Now;
            var list = new List<RechargePackage>();
            var packages = Account.Value.RechargePackageList(true);
            foreach (var package in packages)
            {
                if (package.BeginDate.HasValue)
                {
                    if (package.BeginDate >= now)
                    {
                        if (package.EndDate.HasValue)
                        {
                            if (package.EndDate <= now)
                            {
                                if (PackageValidate(package, userId))
                                {
                                    list.Add(package);
                                }
                            }
                        }
                        else
                        {
                            if (PackageValidate(package, userId))
                            {
                                list.Add(package);
                            }
                        }
                    }
                }
                else
                {
                    if (package.EndDate.HasValue)
                    {
                        if (package.EndDate <= now)
                        {
                            if (PackageValidate(package, userId))
                            {
                                list.Add(package);
                            }
                        }
                    }
                    else
                    {
                        if (PackageValidate(package, userId))
                        {
                            list.Add(package);
                        }
                    }
                }
            }
            return list;
        }

        private bool PackageValidate(RechargePackage package, int userId)
        {
            if (package.Limit == PackageLimit.NTimesOnly)
            {
                return package.Usage < package.LimitTimes && PackageValidateInternal(package, userId);
            }
            if (package.Limit == PackageLimit.NTimesPerCustomer)
            {
                var count = Account.Value.AccountRechargeCountGet(userId, package.Id, status: true);

                return count < package.LimitTimes && PackageValidateInternal(package, userId);
            }
            return PackageValidateInternal(package, userId);
        }

        private bool PackageValidateInternal(RechargePackage package, int userId)
        {
            if (package.Requirements != null && package.Requirements.Any(o => o.Status))
            {
                return package.Requirements.All(requirement => HandlerPackageRequirement(requirement, userId));
            }
            return true;
        }

        private bool HandlerPackageRequirement(RechargePackageRequirement requirement, int userId)
        {
            if (requirement.Status)
            {
                if (requirement.Id == 1) //首次充值
                {
                    return Account.Value.AccountRechargeCountGet(userId) == 0;
                }
            }
            return false;
        }

        protected IList<PaymentPlatform> PaymentPlatformList()
        {
            return PaymentEBankList().Select(o => o.PaymentPlatform).Where(o => o.Status).ToList();
        }

        protected IList<PaymentEBank> PaymentEBankList()
        {
            var key = CacheKey.Accont.PaymentEBanks;
            return MemcachedClient.Put(key, () => Account.Value.PaymentEBankList(true));

        }
    }
}
